﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using System.Threading;

namespace DynSim.Integration.WinForm
{
    public partial class DynSimViewer : UserControl
    {
        private DynSimViewerComponent component;

        public bool Crop { get; set; }
        public Microsoft.Xna.Framework.Rectangle CropRectangle { get; set; }

        public DynSimViewer()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            this.HandleCreated += new EventHandler(XNAViewer_HandleCreated);
            this.HandleDestroyed += new EventHandler(XNAViewer_HandleDestroyed);
        }

        private void XNAViewer_HandleDestroyed(object sender, EventArgs e)
        { if (component != null) StopGame(false); }

        private void XNAViewer_HandleCreated(object sender, EventArgs e)
        { if (component != null) ResumeGame(); }

        public void RunGame(Microsoft.Xna.Framework.Game game)
        {
            if (component != null) throw new Exception("Stop Game Before Running A New Game");

            component = new DynSimViewerComponent(game, this);
            game.Components.Add(component);
            new Thread(new ParameterizedThreadStart(StartGameLoop)).Start(game);
            lblInfo.Visible = false;
        }

        public void PauseGame()
        { component.PauseGame(); }

        public void ResumeGame()
        { component.ResumeGame(); }

        public void StopGame()
        { StopGame(false); }

        private void StopGame(bool disposing)
        {
            component.PauseGame();
            component.Game.Exit();
            component.Dispose();
            component = null;
            if (!disposing) lblInfo.Visible = true;
        }

        private static void StartGameLoop(object game)
        { ((Microsoft.Xna.Framework.Game)game).Run(); }

        public override Size GetPreferredSize(Size proposedSize)
        {
            if (component != null)
            {
                if (Crop)
                    return new Size(CropRectangle.Width, CropRectangle.Height);
                else if (component.Game.GraphicsDevice != null)
                    return new Size(component.Game.GraphicsDevice.PresentationParameters.BackBufferWidth, component.Game.GraphicsDevice.PresentationParameters.BackBufferHeight);
            }
            return base.GetPreferredSize(proposedSize);
        }
    }
}
